package com.hzy.fivepalace.wx.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.hzy.fivepalace.common.consts.CommConsts;
import com.hzy.fivepalace.common.consts.RedisKeyConsts;
import com.hzy.fivepalace.common.exception.AppException;
import com.hzy.fivepalace.common.service.redis.RedisCache;
import com.hzy.fivepalace.common.type.CouponsQueryTypeEnums;
import com.hzy.fivepalace.common.type.CouponsStatusEnums;
import com.hzy.fivepalace.common.type.OrderStatusEnums;
import com.hzy.fivepalace.common.util.DateUtils;
import com.hzy.fivepalace.common.util.IpUtils;
import com.hzy.fivepalace.common.util.OrderUtils;
import com.hzy.fivepalace.common.util.ResponseUtil;
import com.hzy.fivepalace.db.dao.DtsOrderGoodsMapper;
import com.hzy.fivepalace.db.dao.DtsOrderMapper;
import com.hzy.fivepalace.db.dao.ex.CommonMapperEx;
import com.hzy.fivepalace.db.dao.ex.DtsCartMapperEx;
import com.hzy.fivepalace.db.dao.ex.DtsCouponUserMapperEx;
import com.hzy.fivepalace.db.domain.*;
import com.hzy.fivepalace.db.service.*;
import com.hzy.fivepalace.db.vo.wx.*;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 统一购买服务
 */
@Service
public class WxBuyService {

    private static final Logger logger = LoggerFactory.getLogger(WxBuyService.class);
    @Resource
    private Redisson redisson;
    @Resource
    private DtsGoodsProductService productService;
    @Resource
    private DtsGoodsService goodsService;
    @Resource
    private DtsUserService userService;
    @Resource
    private DtsAddressService addressService;
    @Resource
    private DtsCouponUserMapperEx couponUserMapperEx;
    @Resource
    private DtsSystemConfigService systemConfigService;
    @Resource
    private DtsCartMapperEx cartMapperEx;
    @Resource
    private DtsGoodsSpecificationService specificationService;
    @Resource
    private WxPayService wxPayService;
    @Resource
    private DtsRegionService regionService;
    @Resource
    private DtsOrderMapper dtsOrderMapper;
    @Resource
    private DtsOrderGoodsMapper dtsOrderGoodsMapper;
    @Resource
    private DtsCartService cartService;
    @Resource
    private RedisCache redisCache;
    @Resource
    private PayService payService;
    @Resource
    private CommonMapperEx commonMapperEx;
    @Resource
    private DtsGroupOpenListService groupOpenListService;
    @Resource
    private DtsGroupProductService groupProductService;

    /**
     * 微信小程序支付回调地址
     */
    @Value("${hzy.wx.notify-url}")
    private String wxPayCallbackUrl;


    /**
     * 提交订单
     *
     * @param userId
     * @param query
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Object submitOrder(Integer userId, WxConfirmOrderQueryVo query) {
        RLock lock = redisson.getLock("wx_submitOrder_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);

        DtsUser user = userService.findById(userId);
        if (null == user) {
            logger.error("查询确认订单页面失败:用户不存在，userId:{}", userId);
            lock.unlock();
            return ResponseUtil.unlogin();
        }

        if(query.getOrderType() == 1){
            //如果不是会员用户不能购买提交
            if(user.getVipType() == 0){
                lock.unlock();
                return ResponseUtil.fail("您不是会员，不能参与该活动");
            }
        }


        //调用确认订单方法，获取相应信息
        Object confirmOrderResult = confirmOrder(userId, query, true);
        JSONObject confirmOrderJson = JSONObject.parseObject(JSON.toJSONString(confirmOrderResult));
        if (confirmOrderJson.getIntValue("code") != ResponseUtil.SUCCESS_CODE) {//未成功直接返回
            lock.unlock();
            return confirmOrderResult;
        }
        WxConfirmOrderResultVo result = null;
        try{
            result = confirmOrderJson.getObject("data", WxConfirmOrderResultVo.class);
        }catch (Exception e){
            e.printStackTrace();
            lock.unlock();
            throw new AppException("系统错误请重试");
        }

        //获取收货地址
        DtsAddress address = result.getAddress();

        //当前系统时间
        Calendar calendar = Calendar.getInstance();
        LocalDateTime dateLocal = LocalDateTime.now();
        Date date = new Date();

        //响应结果
        Map<String, Object> responseResult = new HashMap<>();
        //初始化返回信息
        //微信支付数据
        responseResult.put("wxPayInfo", null);
        //是否免费订单
        responseResult.put("freeOrder", result.isFreeOrder());
        //订单编号
        responseResult.put("orderNo", null);
        //订单id
        responseResult.put("orderId", null);
        //订单结束时间
        responseResult.put("orderEndTime", null);
        //生成订单编号
        String orderNo = OrderUtils.generateOrderNo();
        DtsOrderWithBLOBs order = new DtsOrderWithBLOBs();
        order.setUserId(userId);
        order.setOrderSn(orderNo);
        order.setOutTradeNo(orderNo);

        if (result.isFreeOrder()) {//免费订单就是待发货
            order.setOrderStatus((short) OrderStatusEnums.TYPE1.getType());
        } else {//非免费订单就待付款
            order.setOrderStatus((short) OrderStatusEnums.TYPE0.getType());
        }
        order.setConsignee(address.getName());
        order.setMobile(address.getMobile());
        if (query.getFreightType().intValue() == 0) {//物流的话，拼接完整地址
            String pname = regionService.findById(address.getProvinceId()).getName();
            String cname = regionService.findById(address.getCityId()).getName();
            String aname = regionService.findById(address.getAreaId()).getName();
            order.setAddress(pname + cname + aname + address.getAddress());
        }


        order.setMessage(query.getRemark());
        order.setGoodsPrice(result.getSubtotal());
        order.setFreightPrice(result.getCost());
        order.setCouponPrice(result.getDiscountsMoney());
        order.setOrderPrice(result.getPayMoney());
        order.setActualPrice(new BigDecimal("0.00"));
        order.setEndTime(DateUtils.addMinutes(date, CommConsts.orderValidMinute).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
        order.setAddTime(dateLocal);
        order.setUpdateTime(dateLocal);
        order.setFreightType(query.getFreightType().byteValue());
        order.setCouponsId(query.getCouponsId());
        order.setDeleted(false);
        order.setComments((short) result.getGoodsList().size());
        order.setIsByVip(false);
        order.setOrderType(query.getOrderType());
        order.setGroupId(query.getGroupId());

        order.setIsPinkOwner(0);
        order.setPinkId(0);
        //拼团订单，找出当前未满员的一个团购
        if(query.getOrderType() == 1){
            DtsGroupProduct groupProduct = groupProductService.findById(query.getGroupId());
            if(groupProduct != null){
                BigDecimal goodsSumPrice = groupProduct.getGroupBuyPrice().multiply(new BigDecimal(query.getNumber()));
                BigDecimal cost = getCost(goodsSumPrice, query.getFreightType());//运费
                order.setOrderPrice(groupProduct.getGroupBuyPrice().add(cost));
            }
        }

        //订单信息入库
        dtsOrderMapper.insertSelective(order);

        //购买的商品信息入库
        List<Integer> productIds = new ArrayList<>();
        result.getGoodsList().forEach(goods -> {
            DtsOrderGoods orderGoods = new DtsOrderGoods();
            orderGoods.setGoodsId(goods.getGoodsId());
            orderGoods.setOrderId(order.getId());
            orderGoods.setGoodsName(goods.getGoodsName());
            orderGoods.setProductId(goods.getProductId());
            orderGoods.setNumber(goods.getNumber().shortValue());
            orderGoods.setPrice(goods.getPrice());
            orderGoods.setSpecifications(new String[]{goods.getSpecifications()});
            orderGoods.setPicUrl(goods.getGoodsImg());
            orderGoods.setAddTime(dateLocal);
            orderGoods.setUpdateTime(dateLocal);
            orderGoods.setDeleted(false);
            dtsOrderGoodsMapper.insertSelective(orderGoods);
            //减少货品库存
            productService.reduceStock(goods.getProductId(), goods.getNumber().shortValue());
            productIds.add(goods.getProductId());
        });
        //删除用户购物车中商品
        cartService.deleteByProductIdAndUserId(productIds, user.getId());

        if (null != query.getCouponsId() && query.getCouponsId().intValue() > 0) {//使用了优惠券就更改优惠券为已使用
            couponUserMapperEx.setCouponsStatusIsUse(query.getCouponsId());
        }

        if (!result.isFreeOrder()) {//不为免费订单，就去创建微信支付
            try {
                WxPayMpOrderResult wxPayMpOrderResult = createWxAPPOrder("购买商品", orderNo, order.getOrderPrice(), user.getWeixinOpenid(), calendar);
                //去掉appid字段返回
                wxPayMpOrderResult.setAppId(null);
                //设置微信支付数据
                responseResult.put("wxPayInfo", wxPayMpOrderResult);
                //订单编号
                responseResult.put("orderNo", orderNo);
                //订单结束时间
                responseResult.put("orderEndTime", DateUtils.addMinutes(date, CommConsts.orderValidMinute).getTime());
                //插入一个缓存，用于订单过期监听
                redisCache.setCacheObject(RedisKeyConsts.ORDER_TIME_OUT_LISTENING_KEY + order.getOrderSn(), order.getOrderSn(), CommConsts.orderValidMinute, TimeUnit.MINUTES);
            } catch (Exception e) {
                logger.error("提交订单失败：调用微信支付服务异常,userId:{},msg:{}", userId, e.getMessage());
                lock.unlock();
                throw new AppException("微信支付服务异常");
            }
        } else {
            try {
                //支付完成后处理
                payService.payment(order);
            } catch (Exception e) {
                logger.error("免费订单支付完成后处理异常:orderNo:{},msg:{}", orderNo, e.getMessage());
                lock.unlock();
                throw new AppException(e.getMessage());
            }
        }
        //订单id
        responseResult.put("orderId", order.getId());
        logger.info("订单创建成功:userId:{},入参报文:{},响应报文:{}", userId, JSON.toJSONString(query), JSON.toJSONString(responseResult));
        lock.unlock();
        return ResponseUtil.ok(responseResult);
    }

    /**
     * 创建微信小程序支付订单
     *
     * @param goodsName  商品名称
     * @param orderNo    订单编号
     * @param price      价格
     * @param userOpenid 用户openid
     * @param calendar   时间
     * @return
     * @throws WxPayException
     */
    public WxPayMpOrderResult createWxAPPOrder(String goodsName,
                                               String orderNo, BigDecimal price, String userOpenid,
                                               Calendar calendar) throws WxPayException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //拼接微信小程序支付参数
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        //支付回调地址
        wxPayUnifiedOrderRequest.setNotifyUrl(wxPayCallbackUrl);
        //商品名称
        wxPayUnifiedOrderRequest.setBody(goodsName);
        //订单编号
        wxPayUnifiedOrderRequest.setOutTradeNo(orderNo);
        //订单金额
        wxPayUnifiedOrderRequest.setTotalFee(price.multiply(new BigDecimal(100)).intValue());
        //交易类型为JSAPI支付
        wxPayUnifiedOrderRequest.setTradeType("JSAPI");
        wxPayUnifiedOrderRequest.setSpbillCreateIp(null == request ? "127.0.0.1" : IpUtils.getIpAddr(request));
        //用户在当前小程序中的唯一标识
        wxPayUnifiedOrderRequest.setOpenid(userOpenid);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        //交易起始时间
        wxPayUnifiedOrderRequest.setTimeStart(formatter.format(calendar.getTime()));
        //交易结束时间 (当前15分钟后的时间-1分钟也就是9分钟，避免在到期前几秒支付成功后，redis监听过期订单时该订单被删除，系统订单有效是15分钟，传给微信的是15-1为14分钟)
        wxPayUnifiedOrderRequest.setTimeExpire(DateUtils.getMinuteAfter(calendar, CommConsts.orderValidMinute - 1));
        return wxPayService.createOrder(wxPayUnifiedOrderRequest);
    }


    /**
     * 商品确认订单，查询一些关键信息返回
     *
     * @param userId
     * @param query
     * @param submitCall
     * @return
     */
    public Object confirmOrder(Integer userId, WxConfirmOrderQueryVo query, boolean submitCall) {
        if (!submitCall) {
            DtsUser user = userService.findById(userId);
            if (null == user) {
                logger.error("查询确认订单页面失败:用户不存在，userId:{}", userId);
                return ResponseUtil.unlogin();
            }
        }

        WxConfirmOrderResultVo result = resultVoInitialize();

        DtsAddress address = null;
        if (!submitCall) {

            if (null != query.getFreightType()) {
                if (query.getFreightType() != 1 && query.getFreightType() != 0) {
                    return ResponseUtil.fail("参数【freightType】错误");
                }
                if (query.getFreightType() == 0) {//物流就校验收货地址
                    if (null != query.getAddressId() && query.getAddressId().intValue() > 0) {//传入了收货地址就校验收货地址是否为当前用户的
                        address = addressService.selectById(query.getAddressId(), userId);
                        if (null == address) {
                            return ResponseUtil.fail("收货地址无效,请重新选择");
                        }
                        result.setAddress(address);
                    }
                }
            }


        } else {
            if (null == query.getFreightType()) {
                return ResponseUtil.fail("未选择配送方式");
            }
            if (query.getFreightType() != 1 && query.getFreightType() != 0) {
                return ResponseUtil.fail("参数【freightType】错误");
            }
            if (query.getFreightType() == 0) {//物流就校验收货地址
                if (null == query.getAddressId() || query.getAddressId().intValue() < 1) {
                    return ResponseUtil.fail("未选择收货地址");
                }
                address = addressService.selectById(query.getAddressId(), userId);
                if (null == address) {
                    return ResponseUtil.fail("收货地址无效,请重新选择");
                }
                //判断收货地址是否可以发货
                if (!commonMapperEx.isDeliveryByProvinceIdAndCityId(address.getProvinceId(), address.getCityId())) {
                    return ResponseUtil.fail("该地区无法正常发货");
                }

            } else {
                if (StringUtils.isBlank(query.getConsignee())) {
                    return ResponseUtil.fail("请填写收货人姓名");
                }
                if (StringUtils.isBlank(query.getMobile())) {
                    return ResponseUtil.fail("请填写收货人手机号");
                }
                address = new DtsAddress();
                address.setMobile(query.getMobile());
                address.setName(query.getConsignee());
            }
            result.setAddress(address);
        }


        if (query.isCartBuy()) {//购物车购买
            List<WxCartVo> cartVoList = getUserCartList(userId);
            if (CollectionUtils.isEmpty(cartVoList)) {
                return ResponseUtil.fail("购物车还没有已选中的商品");
            }
            //商品总金额
            BigDecimal goodsSumPrice = new BigDecimal(0);


            //判断购物车是否需要分组结算
            Map<Boolean, List<WxCartVo>> groupByMap = cartVoList.stream().collect(Collectors.groupingBy(WxCartVo::getIsSince));
            boolean isGroup = groupByMap.size() > 1;//map大于1就是需要分组
            if (isGroup && (null == query.getGroupBySettlementId())) {
                if (!submitCall) {
                    List<WxGroupBySettlementVo> groupBySettlementList = new ArrayList<>();
                    for (Map.Entry entry : groupByMap.entrySet()) {
                        boolean isSince = (boolean) entry.getKey();
                        List<WxCartVo> cartList = (List<WxCartVo>) entry.getValue();

                        WxGroupBySettlementVo wxGroupBySettlementVo = new WxGroupBySettlementVo();
                        wxGroupBySettlementVo.setGroupBySettlementId(isSince ? 2L : 1L);
                        wxGroupBySettlementVo.setTitle(isSince ? "支持自提下单的商品(需单独结算)" : "仅支持物流下单的商品(需单独结算)");
                        BigDecimal sumPrice = new BigDecimal("0.00");
                        String goodsName = cartList.get(0).getGoodsName().replaceAll("\\n|\\t", "");
                        if (cartList.size() > 1) {
                            goodsName = goodsName + "等" + cartList.size() + "件商品";
                        }
                        List<String> goodsImgList = new ArrayList<>();
                        for (WxCartVo item : cartList) {
                            sumPrice = sumPrice.add((item.getNewPrice().multiply(new BigDecimal(item.getNumber().intValue()))));
                            goodsImgList.add(item.getPicUrl());
                        }
                        wxGroupBySettlementVo.setTotal(sumPrice);
                        wxGroupBySettlementVo.setSubheading(goodsName);
                        wxGroupBySettlementVo.setGoodsImgList(goodsImgList);
                        groupBySettlementList.add(wxGroupBySettlementVo);
                    }
                    return ResponseUtil.groupBySettlement(groupBySettlementList);
                } else {
                    return ResponseUtil.fail("订单需分开结算,请返回重新下单");
                }
            } else if (isGroup && (null != query.getGroupBySettlementId())) {
                if (query.getGroupBySettlementId().intValue() != 1 && query.getGroupBySettlementId().intValue() != 2) {
                    return ResponseUtil.fail("参数【groupBySettlementId】错误");
                }
                List<WxCartVo> cartVoListNew = new ArrayList<>();
                for (WxCartVo item : cartVoList) {
                    if (query.getGroupBySettlementId().intValue() == 1 && !item.getIsSince()) {
                        cartVoListNew.add(item);
                    } else if (query.getGroupBySettlementId().intValue() == 2 && item.getIsSince()) {
                        cartVoListNew.add(item);
                    }
                }

                cartVoList = cartVoListNew;
                if (CollectionUtils.isEmpty(cartVoListNew)) {
                    return ResponseUtil.fail("参数【groupBySettlementId】错误");
                }
            }

            //商品信息集合
            List<WxConfirmOrderGoodsVo> goodsList = new ArrayList<>();

            result.setSupportSince(cartVoList.get(0).getIsSince());

            if (!submitCall) {
                if (null != query.getFreightType() && query.getFreightType() == 1 && !result.isSupportSince()) {
                    return ResponseUtil.fail("本次订单不支持自提");
                }
            } else {
                if (query.getFreightType() == 1 && !result.isSupportSince()) {
                    return ResponseUtil.fail("本次订单不支持自提");
                }
            }

            for (WxCartVo item : cartVoList) {
                if (item.getInventory().intValue() < item.getNumber()) {
                    return ResponseUtil.fail("购物车中存在库存不足的货品");
                }
                // 商品信息
                DtsGoods goods = goodsService.selectById(item.getGoodsId());
                if (null == goods) {
                    return ResponseUtil.fail("购物车中有不存在或已下架的商品");
                }
                //商品总金额为货品价格乘以数量
                goodsSumPrice = goodsSumPrice.add(item.getNewPrice().multiply(new BigDecimal(item.getNumber())));
                //拼装商品信息
                WxConfirmOrderGoodsVo orderGoodsVo = new WxConfirmOrderGoodsVo();
                orderGoodsVo.setGoodsId(goods.getId());
                orderGoodsVo.setProductId(item.getProductId());
                orderGoodsVo.setGoodsName(goods.getName());
                orderGoodsVo.setGoodsImg(item.getPicUrl());
                orderGoodsVo.setNumber(item.getNumber().intValue());
                orderGoodsVo.setPrice(item.getNewPrice().multiply(new BigDecimal(item.getNumber())));//商品金额为，数量乘货品价格
                orderGoodsVo.setSpecifications(Arrays.toString(item.getSpecifications()));
                goodsList.add(orderGoodsVo);
            }

            result.setCost(getCost(goodsSumPrice, query.getFreightType()));//运费
            result.setSubtotal(goodsSumPrice);//小计
            result.setGoodsList(goodsList);//商品信息

            result.setCouponsList(getUserCouponsList(userId, goodsSumPrice));//优惠券信息
            result.setPayMoney(goodsSumPrice.add(result.getCost()));//总计：商品总价+运费
        } else {//单独下单


            if (query.getNumber() < 1) {
                return ResponseUtil.fail("购买数量小于1");
            }
            if (null == query.getSpecificationId() || query.getSpecificationId() < 1) {
                return ResponseUtil.fail("参数【specificationId】为空");
            }
            String specificationFather = null;//父规格名称
            String specificationChild = null;//子规格名称
            //子规格的货品id
            Integer childProductxId = null;
            //获取规格信息
            DtsGoodsSpecification specification = specificationService.selectById(query.getSpecificationId());
            if (null != specification && specification.getPid().intValue() != 0) {//如果是子级规格，就去查主规格
                //拼接子规格名称
                specificationChild = specification.getSpecification() + ": " + specification.getValue();
                //设置子规格的货品id
                childProductxId = specification.getGoodsPoroductId();
                //查询主规格
                specification = specificationService.selectById(specification.getPid());
            } else if (null != specification && specification.getPid().intValue() == 0) {//如果是主规格，就校验他下面是否有子规格
                if (commonMapperEx.isHaveChildSpecification(specification.getId())) {//如果有子规格，就代表参数specificationId传入错误
                    return ResponseUtil.fail("参数【specificationId】错误");
                }
            }
            if (null == specification) {
                return ResponseUtil.badArgument("规格不存在或已下架");
            }
            //再次拼接父规格名称
            specificationFather = specification.getSpecification() + ": " + specification.getValue();
            //拼接完整的规格名称
            String[] specificationName = new String[0];
            if (!StringUtils.isBlank(specificationFather) && !StringUtils.isBlank(specificationChild)) {
                specificationName = new String[]{specificationFather, specificationChild};
            } else if (StringUtils.isBlank(specificationFather) && !StringUtils.isBlank(specificationChild)) {
                specificationName = new String[]{specificationChild};
            } else if (!StringUtils.isBlank(specificationFather) && StringUtils.isBlank(specificationChild)) {
                specificationName = new String[]{specificationFather};
            }
            //货品价格
            BigDecimal productPrice = new BigDecimal("99999");
            //货品库存
            Integer productNumber = 0;
            //货品id
            Integer productId = specification.getGoodsPoroductId();
            DtsGoodsProduct product = productService.selectById(productId);
            if (null == product) {
                return ResponseUtil.fail("货品不存在或已下架");
            }
            productPrice = product.getPrice();//获取货品价格

            DtsGoodsProduct childProduct = null;//子规格的货品信息
            if (null != childProductxId) {//如果子规格的货品id不为null,就查询子规格的货品信息
                childProduct = productService.selectById(childProductxId);
                if (null == childProduct) {
                    return ResponseUtil.fail("货品不存在或已下架");
                }
                productNumber = childProduct.getNumber();//获取货品库存
            }else{//如果子规格的货品id为null,那么库存一定是主规格的货品库存
                productNumber = product.getNumber();//获取货品库存
            }

            if (productNumber.intValue() < query.getNumber()) {
                return ResponseUtil.fail("货品库存不足");
            }
            // 商品信息
            DtsGoods goods = goodsService.selectById(product.getGoodsId());
            if (null == goods) {
                return ResponseUtil.fail("商品不存在或已下架");
            }
            if (!submitCall) {
                if (null != query.getFreightType() && query.getFreightType() == 1 && !goods.getIsSince()) {
                    return ResponseUtil.fail("该商品不支持自提");
                }
            } else {
                if (query.getFreightType() == 1 && !goods.getIsSince()) {
                    return ResponseUtil.fail("该商品不支持自提");
                }
            }

            //商品总金额为货品价格乘以数量
            BigDecimal goodsSumPrice = productPrice.multiply(new BigDecimal(query.getNumber()));

            result.setCost(getCost(goodsSumPrice, query.getFreightType()));//运费

            result.setSubtotal(goodsSumPrice);//小计

            //拼装商品信息
            WxConfirmOrderGoodsVo orderGoodsVo = new WxConfirmOrderGoodsVo();
            orderGoodsVo.setGoodsId(goods.getId());
            orderGoodsVo.setProductId(null == childProductxId ? productId : childProductxId);
            orderGoodsVo.setGoodsName(goods.getName());
            orderGoodsVo.setGoodsImg(product.getUrl());
            orderGoodsVo.setNumber(query.getNumber());
            orderGoodsVo.setPrice(goodsSumPrice);
            orderGoodsVo.setSpecifications(Arrays.toString(specificationName));
            List<WxConfirmOrderGoodsVo> goodsList = new ArrayList<>();
            goodsList.add(orderGoodsVo);
            result.setGoodsList(goodsList);//商品信息
            //返回是否支持自提
            result.setSupportSince(goods.getIsSince());
            result.setCouponsList(getUserCouponsList(userId, goodsSumPrice));//优惠券信息
            result.setPayMoney(goodsSumPrice.add(result.getCost()));//总计：商品总价+运费



            result.setOrderType(query.getOrderType());
            result.setGroupId(query.getGroupId());
            //团购类型
            if(query.getOrderType() == 1){
                DtsGroupProduct groupProduct = groupProductService.getGroupProduct(query.getGroupId());
                if(groupProduct != null){

                    goodsSumPrice = groupProduct.getGroupBuyPrice().multiply(new BigDecimal(query.getNumber()));

                    result.setCost(getCost(goodsSumPrice, query.getFreightType()));//运费

                    result.setSubtotal(goodsSumPrice);//小计

                    result.setPayMoney(groupProduct.getGroupBuyPrice().add(result.getCost()));//总计：商品总价+运费
                }
                result.setGroupProduct(groupProduct);
            }

        }

        if (null != query.getCouponsId() && query.getCouponsId().intValue() > 0) {//传入了优惠券id就校验优惠券是否可用
            Object checkCouponsResult = checkCoupons(query.getCouponsId(), userId, result.getPayMoney());
            if (checkCouponsResult instanceof String) {
                return ResponseUtil.fail(String.valueOf(checkCouponsResult));
            }

            if (checkCouponsResult instanceof WxUserCouponsVo) {
                WxUserCouponsVo userCouponsVo = (WxUserCouponsVo) checkCouponsResult;
                result.setDiscountsMoney(userCouponsVo.getMoney());//优惠金额
                result.setPayMoney(result.getPayMoney().subtract(userCouponsVo.getMoney()));//总计：总价减去优惠券金额
            }
        }

        result.setFreeOrder(result.getPayMoney().compareTo(new BigDecimal("0.00")) <= 0);//是否免费订单

        if (result.getPayMoney().compareTo(new BigDecimal("0.00")) <= 0) {//支付金额小于等于0就为0元
            result.setPayMoney(new BigDecimal(0));
        }

        return ResponseUtil.ok(result);
    }

    /**
     * 获取用户购物车列表
     *
     * @param userId
     * @return
     */
    public List<WxCartVo> getUserCartList(Integer userId) {
        List<WxCartVo> cartVoList = new ArrayList<>();
        List<WxCartVo> list = cartMapperEx.getUserCartList(userId);
        if (CollectionUtils.isEmpty(list)) {
            return cartVoList;
        }
        for (WxCartVo item : list) {
            //已卖完的,和数量小于1的不选择
            if (null == item.getInventory() || item.getInventory().intValue() <= 0 || null == item.getNumber() || item.getNumber().intValue() <= 0 || item.getInventory().intValue() < item.getNumber()) {
                item.setChecked(false);
            }
            if (item.getChecked()) {//选中的才添加到cartVoList
                cartVoList.add(item);
            }
        }
        return cartVoList;
    }


    /**
     * 获取用户可用优惠券列表
     *
     * @param userId
     * @param goodsSumPrice
     * @return
     */
    public List<WxUserCouponsVo> getUserCouponsList(Integer userId, BigDecimal goodsSumPrice) {
        List<WxUserCouponsVo> couponsList = new ArrayList<>();
        List<WxUserCouponsVo> list = couponUserMapperEx.getUserCouponsList(CouponsQueryTypeEnums.TYPE0.getId(), userId, null);
        list.forEach(item -> {
            if (goodsSumPrice.compareTo(item.getMinUseMoney()) >= 0) {//判断订单优惠前的价格是否大于等于最低使用优惠券的价格
                long days = Duration.between(LocalDateTime.now(), item.getEndTime()).toDays();
                item.setEndDays(days > 0 ? days + "天后到期" : "即将到期");
                item.setUserId(null);
                couponsList.add(item);
            }
        });
        return couponsList;
    }

    /**
     * 获取运费
     *
     * @param goodsSumPrice
     * @return
     */
    public BigDecimal getCost(BigDecimal goodsSumPrice, Integer freightType) {
        BigDecimal cost = new BigDecimal("0.00");
        if (null == freightType) {
            return cost;
        }
        if (freightType.intValue() == 1) {//自提不需要运费
            return cost;
        }

        DtsSystem dtsSystem = systemConfigService.selectByKey("dts.freight");
        if (null == dtsSystem) {
            return cost;
        }

        String jsonStr = dtsSystem.getKeyValue();
        if (StringUtils.isBlank(jsonStr)) {
            return cost;
        }

        JSONObject json = JSONObject.parseObject(jsonStr);
        if (null == json) {
            return cost;
        }

        //免费包邮金额
        BigDecimal freeFreightMoney = json.getBigDecimal("freeFreightMoney");
        if (null == freeFreightMoney || freeFreightMoney.compareTo(new BigDecimal(0)) <= 0) {//免费包邮金额为空或者小于等于0就代表运费为0
            return cost;
        }

        //运费
        BigDecimal freight = json.getBigDecimal("freight");
        if (null == freight) {
            freight = new BigDecimal(0);
        }
        //判断 是否已满足免费包邮金额
        if (goodsSumPrice.compareTo(freeFreightMoney) >= 0) {
            return cost;
        } else {
            return freight;
        }
    }

    /**
     * 校验优惠券
     *
     * @param couponsId
     * @param userId
     * @param originalPrice
     * @return
     */
    public Object checkCoupons(Integer couponsId, Integer userId, BigDecimal originalPrice) {
        WxUserCouponsVo coupons = couponUserMapperEx.getUserCouponsListDetails(couponsId, userId);
        if (null == coupons) {
            return "选择的优惠券不存在";
        }
        //校验优惠券状态
        if (coupons.getStatus().intValue() != CouponsStatusEnums.TYPE0.getId()) {
            return "选择的优惠券已使用";
        }
        //判断优惠券是否过期
        if (LocalDateTime.now().isAfter(coupons.getEndTime())) {
            return "选择的优惠券已过期";
        }

        if (originalPrice.compareTo(coupons.getMinUseMoney()) < 0) {//判断订单优惠前的价格是否大于等于最低使用优惠券的价格
            return "选择的优惠券最低满" + coupons.getMinUseMoney() + "元起用";
        }
        return coupons;
    }

    /**
     * 确认订单返回参数初始化
     *
     * @return
     */
    public WxConfirmOrderResultVo resultVoInitialize() {
        //初始化价格为默认0.00
        BigDecimal defaultPrice = new BigDecimal("0.00");
        WxConfirmOrderResultVo resultVo = new WxConfirmOrderResultVo();
        resultVo.setCouponsList(new ArrayList<>());
        resultVo.setGoodsList(new ArrayList<>());
        resultVo.setSubtotal(defaultPrice);
        resultVo.setPayMoney(defaultPrice);
        resultVo.setDiscountsMoney(defaultPrice);
        resultVo.setCost(defaultPrice);
        resultVo.setFreeOrder(false);
        resultVo.setSupportSince(false);
        return resultVo;
    }
}
